<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>this指向问题</title>
  </head>

  <body>
    <h1>setInterval和setTimeout 中this指向问题.html</h1>
  </body>
  <script>
    // var num = 0;
    // function Obj() {
    //     this.num = 1;
    //     this.getNum = function () {
    //         console.log(this.num)
    //     };
    //     this.getNumLater = function () {
    //         setTimeout(function () {
    //             console.log(this.num)
    //         }, 1000)
    //     }
    // }
    // var obj = new Obj;
    // obj.getNum() // 1   　打印的是obj.num，值为1
    // obj.getNumLater()// 0   打印的是window.num，值为0

    // 重点：
    // setTimeout中函数内的this是指向了window对象，
    // 这是由于setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象

    // 解决方案
    // 1.将当前对象的this存为一个变量，定时器内的函数利用闭包来访问这个变量
    // var num = 0;
    // function Obj() {
    //     var that = this;    //将this存为一个变量，此时的this指向obj
    //     this.num = 1,
    //         this.getNum = function () {
    //             console.log(this.num);
    //         },
    //         this.getNumLater = function () {
    //             setTimeout(function () {
    //                 console.log(that.num);    //利用闭包访问that，that是一个指向obj的指针
    //             }, 1000)
    //         }
    // }
    // var obj = new Obj;
    // obj.getNum();//1　　打印的是obj.num，值为1
    // obj.getNumLater()//1　　打印的是obj.num，值为1

    // 2.利用bind()方法
    // var num = 0;
    // function Obj() {
    //     this.num = 1,
    //         this.getNum = function () {
    //             console.log(this.num);
    //         },
    //         this.getNumLater = function () {
    //             setTimeout(function () {
    //                 console.log(this.num);
    //             }.bind(this), 1000)    //利用bind()将this绑定到这个函数上
    //         }
    // }
    // var obj = new Obj;
    // obj.getNum();//1　　打印的为obj.num，值为1
    // obj.getNumLater()//1　　打印的为obj.num，值为1

    // 3. 箭头函数
    var num = 0;
    function Obj() {
      (this.num = 1),
        (this.getNum = function() {
          console.log(this.num);
        }),
        (this.getNumLater = function() {
          setTimeout(() => {
            console.log(this.num);
          }, 1000); //箭头函数中的this总是指向外层调用者，也就是Obj
        });
    }
    var obj = new Obj();
    obj.getNum(); //1　　打印的是obj.num，值为1
    obj.getNumLater(); //1　　打印的是obj.num，值为1
  </script>
</html>
